import { useContext, useState, useEffect, useRef, RefObject } from 'react'
import style from './index.module.less'
import { SignContext } from '../../context'
import { PDFSignSchema } from '@src/components/schema/pdf'
import { useDispatch } from 'react-redux'
import { addResizeEvent, delResizeEvent } from '@src/redux/actions/globalEvent'
import $, { data } from 'jquery'
import _ from 'lodash'
import classNames from 'classnames';

function updateLocation (list: PDFSignSchema[], i: number, x: number, y: number, page: number, setSignList: (v: PDFSignSchema[]) => void) {
  const l = [...list]
  const o = l[i]
  o.locationx = x
  o.locationy = y
  o.location_page = page
  setSignList(l)
}

const tUpdateLocation = _.throttle(updateLocation, 50)

interface ItemProps {
  index: number
  data: PDFSignSchema
  width: number
  height: number
  x: number
  y: number
  page: number
  editable: boolean
  setMoveIndex: (v: number) => void
  setSX: (v: number) => void
  setSY: (v: number) => void
  setItemWidth: (v: number) => void
  setItemHeight: (v: number) => void
}

function Item ({ data, width, height, x, y, page, editable, setMoveIndex, index, setSX, setSY, setItemWidth, setItemHeight }: ItemProps) {
  const [left, setLeft] = useState(0)
  const [top, setTop] = useState(0)
  const ref = useRef<HTMLDivElement>(null)
  useEffect(() => {
    setLeft(width * x)
    setTop(page * height + y * height)
  }, [data, width, height, x, y, page])
  return (
    <div ref={ref} className={classNames(style.sign, { [style.disabled]: !editable })} style={{ left: `${left}px`, top: `${top}px`, fontSize: `${width / 798 * 20}px` }}
      onMouseDown={function (e) {
        if (!editable) {
          return undefined
        }
        e.stopPropagation()
        const item = ref.current
        if (!item) {
          return undefined
        }
        const o = $(item)
        const i = o.offset() || { left: 0, top: 0 }
        setSX(e.clientX - i.left)
        setSY(e.clientY - i.top)
        setItemWidth(o.outerWidth() || 0)
        setItemHeight(o.outerHeight() || 0)
        setMoveIndex(index)
      }}
    >
      <div className={style['sign-name']}>{data.name}</div>
      <div className={style.notice}>可拖动</div>
    </div>
  )
}

interface Props {
  fileid: string
  ready: boolean
  width: number
  height: number
  numPages: number
  editable: boolean
}

function Main ({ fileid, ready, width, height, numPages, editable }: Props) {
  const c = useContext(SignContext)
  const ref = useRef<HTMLDivElement>(null)
  const [moveIndex, setMoveIndex] = useState(-1)
  const [sx, setSX] = useState(0)
  const [sy, setSY] = useState(0)
  const [itemWidth, setItemWidth] = useState(0)
  const [itemHeight, setItemHeight] = useState(0)
  return (
    <div className={style.container} ref={ref}
      onMouseMove={(e) => {
        const current = ref.current
        if (moveIndex === -1 || !current) {
          return undefined
        }
        const p = $(current).offset() || { left: 0, top: 0 }
        let nx = (e.clientX - sx - p.left)
        let ny = (e.clientY - sy - p.top)
        if (nx + itemWidth > width) {
          nx = width - itemWidth
        } else if (nx < 0) {
          nx = 0
        }
        if (ny + itemHeight > numPages * height) {
          ny = numPages * height
        } else if (ny < 0) {
          ny = 0
        }
        nx = nx / width
        ny = ny / height
        const n = parseInt(`${ny}`)
        tUpdateLocation(c.signList, moveIndex, nx, ny - n, n, c.setSignList)
      }}
      onMouseUp={(e) => {
        const current = ref.current
        if (moveIndex === -1 || !current) {
          return undefined
        }
        const p = $(current).offset() || { left: 0, top: 0 }
        let nx = (e.clientX - sx - p.left)
        let ny = (e.clientY - sy - p.top)
        if (nx + itemWidth > width) {
          nx = width - itemWidth
        } else if (nx < 0) {
          nx = 0
        }
        if (ny + itemHeight > numPages * height) {
          ny = numPages * height
        } else if (ny < 0) {
          ny = 0
        }
        nx = nx / width
        ny = ny / height
        const o = c.signList[moveIndex]
        const n = parseInt(`${ny}`)
        tUpdateLocation(c.signList, moveIndex, nx, ny - n, n, c.setSignList)
        setMoveIndex(-1)
        c.updateSign({ id: o.id, locationx: nx, locationy: ny - n, location_page: n })
      }}
    >
      {c.signList.filter(li => !li.signed_fileid).map((li, i) => {
        return (
          <Item key={i} data={li} x={li.locationx || 0} y={li.locationy || 0} page={li.location_page || 0} index={i} width={width} height={height} setMoveIndex={setMoveIndex} setSX={setSX} setSY={setSY} setItemWidth={setItemWidth} setItemHeight={setItemHeight} editable={editable} />
        )
      })}
    </div>
  )
}

export default Main
